import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import {buildVersionPlugins} from './vite-plugins/build-version.js'
import {buildTimerPlugins} from './vite-plugins/build-timer.js'
import setupExtend from 'vite-plugin-vue-setup-extend'
import { visualizer } from 'rollup-plugin-visualizer';
import legacySwc from 'vite-plugin-legacy-swc'
import eslintPlugin from 'vite-plugin-eslint'
// import legacy from '@vitejs/plugin-legacy'

/**
 * vite-plugin-vue-setup-extend
 * 是一个用于 Vue 3 项目的 Vite 插件，旨在增强 setup 语法糖的功能，使开发更加便捷和高效。
 * 定义组件名称
 * 支持 ES6 模块语法
 * 支持 async/await
 * 支持源代码映射（source map）
 * 
 * rollup-plugin-visualizer
 * 打包分析插件,帮助分析包大小的体积以及引入的依赖关系
 * 
 * legacySwc和legacy
 */


/**
 * Polyfill 是一段代码或一个库，用来为旧版浏览器提供新的 API 支持。
 * Polyfill 实现了那些在新标准中定义但在当前执行环境中不可用的功能。通过使用 Polyfill，你可以使用较新的 JavaScript 特性而不用担心兼容性问题。例如，Promise、fetch 等功能可能在某些旧版浏览器中不被支持，这时就可以使用相应的 Polyfill 来实现这些功能
 *
 * Babel 是一个 JavaScript 编译器，主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的版本，以便在旧版浏览器或环境中运行。
 * 可以转译语法（如箭头函数、解构赋值等），还可以通过插件来处理 JSX、TypeScript 等其他语言特性。此外，Babel 还可以集成 Polyfills 来解决一些语言内置对象和方法的兼容性问题
 * 
 * 
 * @vitejs/plugin-legacy 是一个非常实用的插件，可以帮助你在现代前端开发中轻松实现对旧版浏览器的支持。它通过生成双版本构建文件，既保证了现代浏览器的性能，又兼顾了旧版浏览器的兼容性
 * 
 * 
 * self_machine在默认情况下，Vite 会将所有第三方库打包到一个 vendor.[hash].js 文件中。但通过这段代码，vue3-waterfall-plugin 和 qrcode.vue 会被单独打包到一个名为 self_machine.[hash].js 的文件中
 * 
 * 
 */
export default defineConfig(
  ({mode})=>{
    const isProd = mode === 'production'
    return{
      plugins: [
          vue(),
        buildVersionPlugins(),
        buildTimerPlugins(),
        isProd && setupExtend(), // 可以在setup语法上面命名
        isProd && visualizer({open:false}), // 生成包分析图
        isProd && legacySwc({  //帮助开发者将现代 JavaScript (ESNext) 代码转换为向后兼容的版本，以便在不支持最新 JavaScript 特性的旧版浏览器中也能正常运行。它利用了 swc（Speedy Web Compiler），这是一个非常快速的编译器，用于将新版本的 JavaScript 转换为旧版本，
          targets:['Firefox > 44, ie >= 11'],
          additionalLegacyPolyfills:['regenerator-runtime/runtime']} //作用是向你的项目中添加一个额外的 Polyfill，用于支持旧版浏览器中不支持的 Generator 函数 和 Async/Await 语法。,构建工具会自动将 regenerator-runtime 添加到你的最终打包文件中，从而解决兼容性问题。
        ),
        isProd && eslintPlugin({
          include:['src/**/*.ts','src/**/*.vue', 'src/*.ts', 'src/*.vue'],
          emitWarning:false
        })
      ],
        
      build:{
        outDir:'dist',
        minify:'terser',//用来指定使用哪种混淆器，压缩混淆,需要高度自定义的压缩选项，或者项目中包含复杂的 JavaScript 代码，那么 Terser 可能是更好的选择,求构建速度，并且对于压缩选项的要求不是特别高，Esbuild 则是一个非常优秀的选择。它不仅可以加速你的构建过程，还能简化你的构建工具链
        sourcemap:false, // 生成.map文件
        chunkSizeWarningLimit:1500, //规定触发警告的 chunk 大小。（以 kB 为单位,与未压缩的chunk大小比较）
        terserOptions:{  //传递给 Terser 的更多 minify 选项。
          compress:{
            drop_console:true, //去除console
            drop_debugger:true //去除debugger
          } 
        },
        rollupOptions:{
          output:{
            /**
             * 手动分离依赖进行代码分割 ，默认情况下，Vite/Rollup 会将所有第三方依赖打包到一个 vendor.[hash].js 文件中。
             * 如果你的项目中有多个第三方库，并且这些库的更新频率不同，那么每次构建时，只要有一个依赖发生变化，整个 vendor.[hash].js 文件的哈希值都会改变。这会导致浏览器缓存失效，用户需要重新下载整个文件，即使大部分内容并没有变化。
             * 通过手动分离依赖，例如将 dayjs 和 lodash-es 分别打包到独立的 chunk 中：
             * dayjs 的代码被打包到 dayjs.[hash].js     lodash-es 的代码被打包到 lodash.[hash].js
             * dayjs 更新时，只有 dayjs.[hash].js 的哈希值会改变，而 lodash.[hash].js 的哈希值保持不变，浏览器可以继续使用缓存
             * 
             * 提高了缓存利用率，减少了用户的下载量
             * 加快了页面加载速度，尤其是对于频繁访问的用户
             * 
             */
            manualChunks(id){  // 
              if (/\/node_modules\/dayjs/.test(id)) { 
                return 'dayjs'
               }else if(/\/node_modules\/lodash-es/.test(id)){
                return 'lodash'
               }else if(/\/node_modules\/exceljs/.test(id)){
                return 'exceljs'
               }
            }
          }
        }
      }
    }
})
